
import re
import requests
import collections
import xml.dom.minidom
import xml.etree.cElementTree

from Module.xRayDetection.xray.logs import Logger

def dict2xml(data=None, root='object'):
    xml = f'<{root}>'
    if isinstance(data, dict):
        for key, value in data.items():
            xml += dict2xml(value, key)

    elif isinstance(data, (list, tuple, set)):
        for item in data:
            xml += dict2xml(item, 'string')
    else:
        xml += str(data)

    xml += f'</{root}>'
    return xml

def xml2dict(t: xml.etree.cElementTree.Element):
    t.tag = re.sub('{.*}', '', t.tag)
    d = {t.tag: {} if t.attrib else None}
    children = list(t)
    if children:
        dd = collections.defaultdict(list)
        for dc in map(xml2dict, children):
            for k, v in dc.items():
                dd[k].append(v)
        d = {t.tag: {k: v[0] if len(v) == 1 else v
                     for k, v in dd.items()}}
    if t.attrib:
        d[t.tag].update(('@' + k, v)
                        for k, v in t.attrib.items())
    if t.text:
        text = t.text.strip()
        if children or t.attrib:
            if text:
              d[t.tag]['#text'] = text
        else:
            d[t.tag] = text
    return d

def prettify(xml_):
    def to_node(obj) -> xml.dom.minidom.Node:
        return obj

    xml_ = to_node(xml.dom.minidom.parseString(xml_)).toprettyxml(indent='  ')
    xml_ = re.sub('\n *\n', '\n', xml_)
    return xml_

def request(barcode, logger: Logger):
    content['Items']['SFC'] = barcode

    data = f'<?xml version="1.0" encoding="utf-8"?>\
    <soap:Envelope \
        xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"\
        xmlns:xsd="http://www.w3.org/2001/XMLSchema"\
        xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">\
        <soap:Body>\
            <{op} xmlns="http://tempuri.org/">{dict2xml(content, root="I_IMPORT")}</{op}>\
        </soap:Body>\
    </soap:Envelope>'

    try:
        data = prettify(data)
        
        response = requests.post(url=url, headers=headers, data=data)
        response_ = prettify(response.text)
            
        xml_ = xml.etree.cElementTree.XML(response_)

        result = xml2dict(xml_)
        result_ = result['Envelope']['Body'][f'{op}Response'][f'{op}Result']

        if result_['State'] == '-1':
            logger.log(logger.ERROR, f'{result_}\n{data}')
        else:
            logger.log(logger.INFO, f"{barcode} {result_}")
        
        return result_

    except Exception as e:
        logger.log(logger.ERROR, e, exception=True)
        return {}

host = 'http://10.36.23.93:10124'
host = ''
op = 'CreateMarkingApi'
url = f'{host}/FengYunMenShen.asmx?op={op}'
content = {
    # "LocalTime": f"\/Date({time.time()})\/", 
	"Type": "TEST",
	"Items": {
		"UnusualProcessCode": "2050", # Required x-ray process
		"FoundBadOperationId": "00000000-0000-0000-0000-000000000000",
		"UnqualifiedId": "00000000-0000-0000-0000-000000000000",
		"MarkingCode": "Marking406", #Required x-ray
		# "ProcessCode": "2060", # required, block process: pre-welding 2060
		"ProcessCode": "3220", # required, block process
		"InterceptOperationId": "00000000-0000-0000-0000-000000000000", 
		"Message": "TEST", # message
		"Remark": "TEST", # message
		# "FactoryID": "A801", # factory 1 A801, factory 2 1011
		"FactoryID": "1011", # factory 1 A801, factory 2 1011
		"ExtendParams": None,   
		"SFC": []  # required barcode
    }
}

headers = {
   'Content-Type': 'text/xml;chatset=utf-8'
}

if __name__ == '__main__':
    host = 'http://1.36.23.53:8090'
    url = f'{host}/FengYunMenShen.asmx?op={op}'
    import pprint
    pprint.pprint(request(barcode=['J23707669904', 'J23707669903', 'J24805504290', 'J23707545448']))
